package org.feng.common;

import lombok.extern.slf4j.Slf4j;
import org.feng.entity.PostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * BeanPostProcessor 实现类：在给Bean 注入属性前、后执行一些操作<br>
 * <b>注意：方法返回值不要设置为null</b>
 *
 * @version V1.0
 * @author: fengjinsong
 * @date: 2022年06月29日 11时34分
 */
@Component
@Slf4j
public class BeanPostProcessorImpl implements BeanPostProcessor {
    /**
     * 实例化并依赖注入后，在调用显示的初始化之前进行一些自定义的初始化逻辑
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (canDoSomething(bean)) {
            log.info("BeanPostProcessor#before() beanName={}", beanName);
            log.info("BeanPostProcessor#before() bean={}", bean);
        }
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (canDoSomething(bean)) {
            log.info("BeanPostProcessor#after() beanName={}", beanName);
            log.info("BeanPostProcessor#after() bean={}", bean);
        }
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

    /**
     * 当实例化的bean上，带有{@link PostProcessor} 注解，即需要进行一些操作
     *
     * @param bean 注入到Spring中的bean
     * @return 当需要进行操作时，返回true
     */
    private boolean canDoSomething(Object bean) {
        if (bean == null) {
            return false;
        }
        return bean.getClass().isAnnotationPresent(PostProcessor.class);
    }
}
